package top.korori.sv.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.korori.common.enums.IsDel;
import top.korori.common.exception.BizException;
import top.korori.common.model.PageData;
import top.korori.common.utils.ImageUtils;
import top.korori.oss.service.CosService;
import top.korori.sv.entity.SvUser;
import top.korori.sv.entity.SvUserArea;
import top.korori.sv.entity.bo.SvUserEditBo;
import top.korori.sv.entity.bo.SysSvUserBo;
import top.korori.sv.entity.vo.SvMediaVo;
import top.korori.sv.entity.vo.SvUserInfoVo;
import top.korori.sv.entity.vo.SysSvUserVo;
import top.korori.sv.enums.SvMediaSource;
import top.korori.sv.enums.SvMediaUse;
import top.korori.sv.mapper.SvUserMapper;
import top.korori.sv.service.SvMediaService;
import top.korori.sv.service.SvUserAreaService;
import top.korori.sv.service.SvUserService;
import top.korori.sv.uitls.SvSecurityUtil;

import java.io.IOException;
import java.sql.Date;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static top.korori.sv.uitls.SvSecurityUtil.getUserId;

/**
 * 短视频前台用户 服务实现类
 *
 * @author korori
 */
@Slf4j
@Service
public class SvUserServiceImpl extends ServiceImpl<SvUserMapper, SvUser> implements SvUserService {


    @Autowired
    private SvUserAreaService svUserAreaService;

    @Autowired
    private SvMediaService svMediaService;

    @Autowired
    private CosService cosService;

    @Override
    public SvUser getByAccount(String account) {
        return this.lambdaQuery()
                .eq(Validator.isEmail(account), SvUser::getEmail, account)
                .eq(Validator.isMobile(account), SvUser::getPhone, account)
                .eq(SvUser::getIsDel, IsDel.NORMAL)
                .one();
    }


    @Override
    public SvUser getUserInfo() {
        return this.getById(SvSecurityUtil.getUserId());
    }

    @Override
    public SvUser getByPhone(String phone) {
        return this.lambdaQuery().eq(SvUser::getPhone, phone).eq(SvUser::getIsDel, IsDel.NORMAL).one();
    }

    @Override
    public SvUser getByEmail(String email) {
        return this.lambdaQuery().eq(SvUser::getEmail, email).eq(SvUser::getIsDel, IsDel.NORMAL).one();
    }

    @Override
    public SvUser getByUserName(String userName) {
        return this.lambdaQuery().eq(SvUser::getUserName, userName).one();
    }

    @Override
    public void editInfo(SvUserEditBo svUserEditBo) {
        Long userId = getUserId();
        SvUser dbSvUser = this.getByUserName(svUserEditBo.getUserName());
        if (ObjUtil.isNotNull(dbSvUser) && ObjUtil.notEqual(dbSvUser.getUserId(), userId)) {
            BizException.cast("该名字已经存在");
        }

        LambdaUpdateWrapper<SvUser> updateWrapper = new LambdaUpdateWrapper<>();

        updateWrapper.eq(SvUser::getUserId, userId);

        //修改昵称
        updateWrapper.set(ObjUtil.isNotNull(svUserEditBo.getUserName()), SvUser::getUserName, svUserEditBo.getUserName());

        //修改性别
        updateWrapper.set(ObjUtil.isNotNull(svUserEditBo.getSex()), SvUser::getSex, svUserEditBo.getSex());

        //修改生日
        LocalDate birthday = svUserEditBo.getBirthday();
        if (ObjUtil.isNotNull(birthday)) {
            LocalDate startDate = LocalDate.of(1900, 1, 1);
            LocalDate lastDate = LocalDate.now();
            if (birthday.isBefore(startDate) || birthday.isAfter(lastDate)) {
                BizException.cast("非法生日");
            }
        }

        updateWrapper.set(ObjUtil.isNotNull(birthday), SvUser::getBirthday, birthday);

        //修改描述
        updateWrapper.set(ObjUtil.isNotNull(svUserEditBo.getIntro()), SvUser::getIntro, svUserEditBo.getIntro());


        //修改所在地
        String placeCity = svUserEditBo.getPlaceCity();
        String province = svUserEditBo.getPlaceProvince();


        if (ObjUtil.isNotNull(placeCity) && ObjUtil.isNotNull(province)) {
            List<Integer> ids = svUserAreaService.isExistArea(province,placeCity);
            if (ids.isEmpty()) {
                BizException.cast("非法地区");
            }
            updateWrapper.set(SvUser::getPlaceProvinceId,ids.get(0));
            updateWrapper.set(SvUser::getPlaceCityId,ids.get(1));
        } else if (ObjUtil.isNotNull(province)) {
            Integer provinceId = svUserAreaService.isProvince(province);
            if (ObjUtil.isNull(provinceId)) {
                BizException.cast("非法地区");
            }
            updateWrapper.set(SvUser::getPlaceProvinceId, provinceId);
        }

        this.update(updateWrapper);

    }

    @Override
    public String uploadAvatar(String base64) {

        MultipartFile multipartFile = ImageUtils.base64ToMultipartFile(base64);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
        String datePath = LocalDate.now().format(formatter);
        String fileName = multipartFile.getOriginalFilename();
        String path = "";
        try {
           path = cosService.putObj(multipartFile.getInputStream(),"/avatar/"+datePath+fileName);
        } catch (IOException e) {
            log.error("头像上传失败:{}",e.getMessage());
            throw new BizException("头像上传失败");
        }
        this.lambdaUpdate().eq(SvUser::getUserId, SvSecurityUtil.getUserId()).set(SvUser::getAvatar, path).update();
        return path;
    }

    @Override
    public SvUserInfoVo getLoginInfo() {

        SvUser svUser = baseMapper.selectById(getUserId());
        SvUserInfoVo svUserInfoVo = BeanUtil.copyProperties(svUser, SvUserInfoVo.class);

        Integer placeProvinceId = svUser.getPlaceProvinceId();
        Integer placeCityId = svUser.getPlaceCityId();

        SvUserArea city  = svUserAreaService.getById(placeCityId);
        SvUserArea province = svUserAreaService.getById(placeProvinceId);

        if (ObjUtil.isNotNull(province)){
            svUserInfoVo.setPlaceProvince(province.getName());
        }

        if (ObjUtil.isNotNull(city)){
            svUserInfoVo.setPlaceCity(city.getName());
        }

        if (ObjUtil.isNotEmpty(svUserInfoVo.getBirthday())) {

            String zodiac = DateUtil.getZodiac(svUserInfoVo.getBirthday().getMonthValue() - 1, svUserInfoVo.getBirthday().getDayOfMonth());
            int age = DateUtil.ageOfNow(Date.valueOf(svUserInfoVo.getBirthday()));

            svUserInfoVo.setZodiac(zodiac);
            svUserInfoVo.setAge(age);
        }
        return svUserInfoVo;

    }

    @Override
    public void uploadAvatarFile(MultipartFile multipartFile) {
        SvMediaVo svMediaVo = svMediaService.uploadPic(multipartFile, SvMediaUse.SV_AVATAR.getUse(), SvMediaSource.FRONT.getSource());
        this.lambdaUpdate().eq(SvUser::getUserId, SvSecurityUtil.getUserId()).set(SvUser::getAvatar, svMediaVo.getUrl()).update();
    }

    @Override
    public PageData<SysSvUserVo> getUserList(SysSvUserBo svUserBo) {
        Page<SvUser> page = new Page<>(svUserBo.getPageNum(), svUserBo.getPageSize());
        LambdaQueryWrapper<SvUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(ObjUtil.isNotEmpty(svUserBo.getUserName()),SvUser::getUserName,svUserBo.getUserName());
        queryWrapper.eq(SvUser::getIsDel, IsDel.NORMAL.getCode());
        Page<SvUser> svUserPage = baseMapper.selectPage(page, queryWrapper);
        return PageData.setDataCopyVo(svUserPage, SysSvUserVo.class);
    }

}
























